
package combat.dudes.client.gui.threads.chat;

import java.awt.Color;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.SpringLayout;
import javax.swing.text.DefaultCaret;
import javax.swing.text.html.HTMLDocument;

import combat.dudes.DudesFunctions;
import combat.dudes.client.ClientApp;
import combat.dudes.client.gui.ClientGUI;
import combat.dudes.client.gui.ClientGUITheme;
import combat.dudes.protocol.data.ChatEntry;


/**
 * @author Laurens Andriessen
 * @version 1.0
 */
public class GUIChat {

	private static final JPanel panel = ClientGUI.panelChat;

	/* public static String jsonToChat(String incomingJSON) { // JSONObject
	 * jsonObject = new JSONObject(); // jsonObject.put("test", "test"); //
	 * System.out.println(jsonObject);
	 * 
	 * incomingJSON =
	 * "{\"chats\":[[\"Laurens\",\"Dude\"],[\"Jesper\",\"Ja?\"],[\"Laurens\",\"Hoi!\"]]}"
	 * ;
	 * 
	 * JSONObject receivedJSON = (JSONObject)JSONValue.parse(incomingJSON);
	 * JSONArray chats = (JSONArray)receivedJSON.get("chats"); String
	 * chatTxt = ""; for(int i = 0; i < chats.size(); i++) { JSONArray chat
	 * = (JSONArray)chats.get(i);
	 * 
	 * String who = (String)chat.get(0); int width = 10; int addChars =
	 * width - who.length(); if (addChars < 0) return who.subSequence(0,
	 * width).toString(); final StringBuilder sb = new StringBuilder();
	 * sb.append(who); // Write the content ... while(--addChars > 0)
	 * sb.append("&nbsp;");
	 * 
	 * chatTxt += "<strong>" + sb.toString() + "</strong>" + chat.get(1) +
	 * "<br>\n"; } return chatTxt; } */

	private static final Color inputBgColorGlobal = new Color(215, 255, 189);
	private static final Color inputBgColorTeam = new Color(189, 210, 255);
	private static final Color dudesBorderColor = new Color(170, 170, 170);
	private static final JTextPane showChats = new JTextPane();
	private static final JComboBox chatAudience = new JComboBox();
	private static final JTextField chatTxtInput = new JTextField();
	private static final JButton chatBtnSubmit = new JButton();

	private static final String[] chatAudiences = { "Global", "Team" };

	public GUIChat() {
		synchronized(panel) {

			SpringLayout layout = new SpringLayout();
			panel.setLayout(layout);

			// Set layout (as shown below) - showChats
			// +---------------------------+
			// |...........................|
			// |... JTextPane showChats ...|
			// |...........................|
			// +---------------------------+
			// | x x JPanel inputPanel x x |
			// +---------------------------+


			// Set HTML style
			showChats.setContentType("text/html");
			String bg = Integer.toHexString(ClientGUITheme.guiPanelBg.darker().darker().getRGB());
			String addCSS = "body { background: #" + bg.substring(2, bg.length()) + "; font-family: " + ClientGUITheme.guiFontFixed.getFamily() + ";" + " font-size: "
					+ (ClientGUITheme.guiFontFixed.getSize() - 1)
					+ "pt;"
					+ " margin: 2px; padding: 0; }";
			((HTMLDocument) showChats.getDocument()).getStyleSheet().addRule(addCSS);
			showChats.setEditable(false);
			// Auto scroll down - http://stackoverflow.com/questions/1627028/how-to-set-auto-scrolling-of-jtextarea-in-java-gui
			DefaultCaret caret = (DefaultCaret) showChats.getCaret();
			caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);


			final JScrollPane showChatsScroll = new JScrollPane(showChats);
			showChatsScroll.setBorder(BorderFactory.createLineBorder(dudesBorderColor));
			showChats.setMargin(new Insets(-6, -6, -6, -6));
			showChatsScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
			showChatsScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
			panel.add(showChatsScroll);

			layout.putConstraint(SpringLayout.WEST, showChatsScroll, -1, SpringLayout.WEST, panel);
			layout.putConstraint(SpringLayout.NORTH, showChatsScroll, -1, SpringLayout.NORTH, panel);
			layout.putConstraint(SpringLayout.EAST, showChatsScroll, 1, SpringLayout.EAST, panel);
			layout.putConstraint(SpringLayout.SOUTH, showChatsScroll, -23, SpringLayout.SOUTH, panel);

			// Set layout (as shown below) - inputPanel
			// +---------------------------+
			// | x x x x x x x x x x x x x |
			// | xx JTextPane ShowChats xx |
			// | x x x x x x x x x x x x x |
			// +---------------------------+
			// |.....JPanel inputPanel.....|
			// +---------------------------+
			JPanel inputPanel = new JPanel();
			inputPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
			panel.add(inputPanel);
			layout.putConstraint(SpringLayout.WEST, inputPanel, -1, SpringLayout.WEST, panel);
			layout.putConstraint(SpringLayout.NORTH, inputPanel, -1, SpringLayout.SOUTH, showChatsScroll);
			layout.putConstraint(SpringLayout.EAST, inputPanel, 1, SpringLayout.EAST, panel);
			layout.putConstraint(SpringLayout.SOUTH, inputPanel, 1, SpringLayout.SOUTH, panel);

			inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.X_AXIS));
			inputPanel.add(chatAudience);
			inputPanel.add(chatTxtInput);
			inputPanel.add(chatBtnSubmit);

			// JComboBox chatAudience
			for(int i = 0; i < chatAudiences.length; i++)
				chatAudience.addItem(chatAudiences[i]);
			chatAudience.setEditable(false);
			chatAudience.setSelectedIndex(0);
			chatAudience.setFont(ClientGUITheme.guiFont);
			chatAudience.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent event) {
					switch(chatAudience.getSelectedIndex()) {
						default:
						case 0:
						chatTxtInput.setBackground(inputBgColorGlobal); // Global
						break;
					case 1:
						chatTxtInput.setBackground(inputBgColorTeam); // Team
						break;
				}
			}
			});


			// JTextField chatTxtInput
			chatTxtInput.setFont(ClientGUITheme.guiFontFixed);
			chatTxtInput.setBackground(inputBgColorGlobal);
			chatTxtInput.addKeyListener(new KeyListener() {
				@Override
				public void keyPressed(KeyEvent k) {
					if(k.getKeyCode() == KeyEvent.VK_ENTER) submitChat();
				}
				@Override
				public void keyReleased(KeyEvent k) {}
				@Override
				public void keyTyped(KeyEvent k) {}
			});

			// JButton chatBtnSubmit
			chatBtnSubmit.setText("Send");
			chatBtnSubmit.setFont(ClientGUITheme.guiFont);
			chatBtnSubmit.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent ae) {
					submitChat();
				}
			});

			String chatsTxt = "";
			int lastKnownMessageID = 0;
			while(true) {
				try {
					long start = DudesFunctions.DateTime.getTimeInMs();

					if(ClientApp.SharedVars.getChats().size() > 0) {
						synchronized(ClientGUI.panelChat) {
							for(ChatEntry chat : ClientApp.SharedVars.getNewChats(lastKnownMessageID)) {
								try {
									String rgb = Integer.toHexString(inputBgColorGlobal.getRGB());
									if(chatAudience.getSelectedIndex() == 1) rgb = Integer.toHexString(inputBgColorTeam.getRGB());
									chatsTxt += "<span style='color: #" + rgb.substring(2, rgb.length()) + "'>"; // Global

									String chatsTxtUser = "[" + chat.getUserName() + "] ";
									chatsTxt += chatsTxtUser;

									int wordWrapLimit = (50 - chatsTxtUser.length() < 35) ? 50 - chatsTxtUser.length() : 35;
									String chatMsgTmp = escapeHTML(chat.getMessage());
									if(Math.floor(chatMsgTmp.length() / wordWrapLimit) > 0) {
										for(int l = 0; l < Math.floor(chatMsgTmp.length() / wordWrapLimit); l++) {
											if(l != 0) for(int m = 0; m < chatsTxtUser.length(); m++)
												chatsTxt += "&nbsp;";
											chatsTxt += chatMsgTmp.substring(l * wordWrapLimit, (l + 1) * wordWrapLimit) + "<br />";
										}
									} else {
										chatsTxt += chatMsgTmp + "<br />";
									}
									chatsTxt += "</span>";

									// String img = Painter.class.getResource("icons" + DudesFunctions.File.sep + "smilies" +
									// DudesFunctions.File.sep + "biggrin.gif").toString().replaceFirst("%2520", " ");
									// chatsTxt.replaceAll(":D", "<img src='" + img + "' />");
								} catch(Exception e) {
									ClientApp.onError("Couldn't escape HTML during display...", e, false);
								}

								lastKnownMessageID = ClientApp.SharedVars.getChats().get(ClientApp.SharedVars.getChats().size() - 1).getMessageID();

								showChats.setText(chatsTxt + "<br />");
							}
						}
					}

					DudesFunctions.Status.DelayUpdate(start, 300, Thread.currentThread());
				} catch(Exception e) {
					ClientApp.onError("GUIChat's While-loop is doing goofy", e, false);
				}
			}
		}
	}
	private void submitChat() {
		try {
			if(chatTxtInput.getText() != "") {
				ClientApp.SharedVars.chat.sendChat(new ChatEntry(ClientApp.SharedVars.chat.getNewMessageID(), ClientApp.SharedVars.getMe().getUserName(),
						(chatAudience.getSelectedItem() == "Global") ? null : ClientApp.SharedVars.getMyTeam(), chatTxtInput.getText()));
				chatTxtInput.setText(null);
			}
		} catch(Exception e) {
			ClientApp.onError("Couldn't escape HTML during submit...", e, true);
		}
	}

	// http://www.java2s.com/Code/Java/Servlets/Escapeandunescapestring.htm
	public static String escapeHTML(String str) {
		if(str == null || str.length() == 0)
			return "";

		StringBuffer buf = new StringBuffer();
		int len = str.length();
		for(int i = 0; i < len; ++i) {
			char c = str.charAt(i);
			switch(c) {
				case '&':
					buf.append("&amp;");
					break;
				case '<':
					buf.append("&lt;");
					break;
				case '>':
					buf.append("&gt;");
					break;
				case '"':
					buf.append("&quot;");
					break;
				case '\'':
					buf.append("&apos;");
					break;
				default:
					buf.append(c);
					break;
			}
		}
		return buf.toString();
	}
}
